import cv2
import numpy as np
import tensorflow as tf


def inception_preprocess(img, central_fraction=0.875):
    height, width, channel = img.shape

    if central_fraction:
        bbox_start_h = int(height * (1 - central_fraction) / 2)
        bbox_end_h = int(height - bbox_start_h)
        bbox_start_w = int(width * (1 - central_fraction) / 2)
        bbox_end_w = int(width - bbox_start_w)

        img = img[bbox_start_h: bbox_end_h, bbox_start_w: bbox_end_w]

    img = 2 * (img / 255.) - 1
    return img


def classify_signs(img_path):
    img = cv2.imread(img_path)

    # preprocess image as inception_resnet_v2 does
    img = inception_preprocess(img)

    # resize to model input image size
    img = cv2.resize(img, (299, 299))

    # expand dims to shape [None, 299, 299, 3]
    img = np.expand_dims(img, 0)

    # load model and run testing
    with tf.gfile.GFile('signs/frozen_signs.pb', 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        graph = tf.import_graph_def(graph_def, name='')

        gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.4)
        config = tf.ConfigProto(allow_soft_placement=True, gpu_options=gpu_options)

        with tf.Session(graph=graph, config=config) as sess:
            # get input tensor
            input_tensor = sess.graph.get_tensor_by_name('input:0')

            # get output tensor
            output_tensor = sess.graph.get_tensor_by_name('InceptionResnetV2/Logits/Predictions:0')

            logits = sess.run(output_tensor, feed_dict={input_tensor: img})
            return str(np.argmax(logits[0]))
